#include <jsoncpp/json/json.h>
#include "Log.hpp"
#include <iostream>
#include <string>
using namespace log;
using namespace std;
// 制作协议与序列化与反序列化的类与计算类
// 规定报头为一个显示长度的字符串,每次发来的报文与报头之间用换\r\n分隔

// 报文格式为:
// 报头\r\n数据\r\n
// 序列化和反序列化的英文是serialization and deserialization

// 添加报头

string step = "\r\n";
bool Encode(string &in_data)
{
    if (in_data.empty())
        return false;
    string temp = std::to_string(in_data.size()) + "\r\n" + in_data + "\r\n";
    in_data = temp;
    return true;
};

bool Decode(string &package, string *content)
{
    // 解析报头
    auto pos = package.find(step); // 查看第一个\r\n出现的位置
    if (pos == string::npos)
    {
        LOG(LogLevel::ERROR) << "报头不完整";
        return false; // 如果没有找到\r\n,说明报头不完整，返回false
    }
    string content_str = package.substr(0, pos); // 从头开始到第一个\r\n之前的字符串就是报头
    int content_len = 0;

    content_len = std::stoi(content_str.c_str()); // 将报头字符串转换为整数     即报文长度

    int all_len = content_len + 2 * step.size() + content_str.size(); // 计算报文的总长度

    if (package.size() < all_len)
    {
        LOG(LogLevel::ERROR) << "数据长度不够";
        return false; // 如果数据长度不够，说明报文不完整，返回false
    }

    *content = package.substr(pos + step.size(), all_len); // 从第一个\r\n之后的字符串开始到报文长度结束的字符串就是数据
    package.erase(0, all_len);                             // 把解析完的报文从原字符串中删除
    return true;
}

class Request
{
public:
    Request(int x = 0, int y = 0, char op = '+') : _x(x), _y(y), _op(op)
    {
    }
    void Serialize(string &out_data)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["op"] = _op;
        string data = root.toStyledString(); // 序列化
        out_data = data;
        Encode(out_data); // 添加报头
        // cout << "data: " << out_data << endl;
    }
    bool Deserialize(string &out_data)
    {
        Json::Value root;
        Json::Reader reader;
        bool parsingSuccessful = reader.parse(out_data, root);
        if (!parsingSuccessful)
        {
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["op"].asInt();
        Print();
        return true;
    }

    int X() { return _x; }
    int Y() { return _y; }
    int Op() { return _op; }

    void SetX(int x) { _x = x; }
    void SetY(int y) { _y = y; }
    void SetOp(char op) { _op = op; }

    void Print()
    {
        cout << "x: " << _x << " y: " << _y << " op: " << _op << endl;
    }

private:
    int _x;
    int _y;
    char _op;
};

class Response
{
public:
    Response(int result = 0, int error_code = 0) : _result(result), _error_code(error_code)
    {
    }
    void Serialize(string &out_data)
    {
        Json::Value root;
        root["result"] = _result;
        root["error_code"] = _error_code;
        string data = root.toStyledString(); // 序列化
        out_data = data;
        Encode(out_data); // 添加报头
        // cout << "data: " << out_data << endl;
    }
    bool Deserialize(string &out_data)
    {
        Json::Value root;
        Json::Reader reader;
        bool parsingSuccessful = reader.parse(out_data, root);
        if (!parsingSuccessful)
        {
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        try
        {
            _result = root["result"].asInt();
            _error_code = root["error_code"].asInt(); /* code */
        }
        catch (const std::exception &e)
        {
            std::cerr << e.what() << '\n';
        }

        return true;
    }

    void SetResult(int result) { _result = result; }
    void SetErrorCode(int error_code) { _error_code = error_code; }

    void Print()
    {
        cout << "result: " << _result << " error_code: " << _error_code << endl;
    }

private:
    int _result;
    int _error_code;
};

class Calaculate
{
public:
    void Calculator(Request &request, Response &response)
    {
        switch (request.Op())
        {
        case '+':
        {
            response.SetResult(request.X() + request.Y());
            break;
        }
        case '-':
        {
            response.SetResult(request.X() - request.Y());
            break;
        }
        case '*':
        {
            response.SetResult(request.X() * request.Y());
            break;
        }
        case '/':
        {
            if (request.Y() == 0)
            {
                response.SetErrorCode(1); // 除数不能为0
                return;
            }
            response.SetResult(request.X() / request.Y());
            break;
        }
        case '%':
        {
            if (request.Y() == 0)
            {
                response.SetErrorCode(2); // 除数不能为0
                return;
            }
            response.SetResult(request.X() % request.Y());
            break;
        }
        default:
        {
            response.SetErrorCode(3); // 运算符错误
            return;
        }
        }
    }

private:
};
